% $Header: /cvsroot/html2ps/postscript/box.text.ps,v 1.1 2005/12/18 07:21:37 Konstantin Exp $

/box-text-create {                 % =>
  box-generic-inline-create

% setup box-specific properties
  dup /Text () put
  dup /Encoding ISOLatin1Encoding put
  
% setup inherited method references
  dup box-text-setup-methods
  dup /box-text add-type
} def

/box-text-draw-overline {         % => Text Box
  newpath
  
% Get the thickness of the font underline
  0
  currentfont 
  font-underline-thick             % => Text Box UThick
  setlinewidth                     % => Text Box 

% Get the position of the font underline 
  currentfont 
  font-overline-pos               % => Text Box UPos

  1 index get-left
  2 index get-top
  3 index get-default-baseline
  sub                              % => Text Box UPos X Y'
% Note that UPos is negative
  2 index add                      % => Text Box UPos X Y'

  moveto

  1 index /get-width call-method
  0 
  rlineto
  stroke                           % => Text Box UPos

  pop pop pop
} def

/box-text-draw-line-through {      % => Text Box
  newpath
  
% Get the line thickness
  0
  currentfont 
  font-underline-thick             % => Text Box UThick
  setlinewidth                     % => Text Box 

% Get the position of the font underline 
  currentfont 
  font-line-through-pos            % => Text Box UPos

  1 index get-left
  2 index get-top
  3 index get-default-baseline
  sub                              % => Text Box UPos X Y'
% Note that UPos is negative
  2 index add                      % => Text Box UPos X Y'

  moveto

  1 index /get-width call-method
  0 
  rlineto
  stroke                           % => Text Box UPos

  pop pop pop
} def

/box-text-draw-underline {         % => Text Box
  newpath
  
% Get the line thickness
  0
  currentfont 
  font-underline-thick             % => Text Box UThick
  setlinewidth                     % => Text Box 

% Get the position of the font underline 
  currentfont 
  font-underline-pos               % => Text Box UPos

  1 index get-left
  2 index get-top
  3 index get-default-baseline
  sub                              % => Text Box UPos X Y'
% Note that UPos is negative
  2 index add                      % => Text Box UPos X Y'

  moveto

  1 index /get-width call-method
  0 
  rlineto
  stroke                           % => Text Box UPos

  pop pop pop
} def

/box-text-find-font {              % => Box
  dup /font-size get-css-value
    
  1 index
  /font-family get-css-value       % => Box FontSize FontFamily
  exch scalefont                   % => Box <<Font>>

  exch pop                         % => <<Font>>
} def

/box-text-get-min-width {          % => Context This
  dup get-full-width
  exch pop
  exch pop
} def

/box-text-get-max-width {          % => Context This
  dup get-full-width
  exch pop
  exch pop
} def

/box-text-reflow {                 % => Context Parent This
% Check if we need a line break here (possilble several times in a row, if we
% have a long word and a floating box intersecting with this word

% To prevent infinite loop, we'll use a limit of 100 sequental line feeds

   0                               % => Content Parent This 0(LFs)
   {
     1 add                         % => Context Parent This LFs'

     3 index
     3 index
     3 index
     /maybe-line-break
     call-method                   % => Context Parent This LFs Flag
      
     1 index 100 ge
     or {
       exit
     } if
   } loop                          % => Context Parent This LFs
   pop                             % => Context Parent This 

% Determine the baseline position and height of the text-box using line-height CSS property
   dup box-generic-apply-line-height
    
% set default baseline
   dup get-default-baseline
   1 index put-baseline

% append current box to parent line box
   dup 2 index
   box-container-append-line       % => Context Parent This

% Determine coordinates of upper-left _margin_ corner
   1 index 1 index
   box-generic-guess-corner        % => Context Parent This

% Offset parent current X coordinate
   dup get-full-width
   2 index get-current-x
   add                             % => Context Parent This CX'
   2 index put-current-x           % => Context Parent This

% Extends parents height
   dup get-bottom-margin           % => Context Parent This BM
   2 index
   box-generic-extend-height       % => Context Parent This 

% Update the value of current collapsed margin; pure text (non-span)
% boxes always have zero margin

   2 index context-pop-collapsed-margin
   0 3 index context-push-collapsed-margin

% Clear the stack
  pop pop pop
} def

/box-text-setup {                  % => Box
% select the font used to render current text box
  dup box-text-find-font           % => Box <<Font>>

  dup font-ascender                % => Box <<Font>> Ascender
  1 index font-descender           % => Box <<Font>> Ascender Descender

  3 2 roll
  setfont                          % => Box Ascender Descender

  1 index 3 index put-default-baseline
  
  add
% 1 index /font-size get-css-value min
  1 index put-height               % => Box
  
% determine the width of the current text box
  dup get-text stringwidth         % => Box SX __
  pop                              % => Box SX
  1 index put-width                % => Box

  pop
} def

/box-text-setup-methods {          % => Box
% Setup method references
  dup get-box-dict /Methods get    % => Box Methods
  dup /get-min-width {box-text-get-min-width} put
  dup /get-max-width {box-text-get-max-width} put
  dup /reflow        {box-text-reflow} put
  dup /show          {box-text-show} put
  pop pop
} def

/box-text-show {                   % => Viewport Box    
% Check if current text box will be cut-off by the page edge
% Get Y coordinate of the top edge of the box
  dup get-top-margin               % => Viewport Box Top

% Get Y coordinate of the bottom edge of the box
  1 index get-bottom-margin        % => Viewport Box Top Bottom

  1 index
  4 index viewport-get-bottom
  gt                               % => Viewport Box Top Bottom TopInside

  1 index
  5 index viewport-get-bottom
  gt                               % => Viewport Box Top Bottom TopInside BottomInside

  2 copy 
  not and                          % => Viewport Box Top Bottom TopInside BottomInside TopInside&&!BottomInside
  {                                % => Viewport Box Top Bottom TopInside BottomInside
% If yes, do not draw current text box at all; add an required value
% to the viewport page offset to make the text box fully visible on the next page
    5 index
    viewport-get-offset-delta      % => Viewport Box Top Bottom TopInside BottomInside OD
    
    4 index
    7 index viewport-get-bottom
    sub                            % => Viewport Box Top Bottom TopInside BottomInside OD ODNew
    max                            % => Viewport Box Top Bottom TopInside BottomInside OD'

    6 index
    viewport-put-offset-delta      % => Viewport Box Top Bottom TopInside BottomInside

    pop pop
  } {                              % => Viewport Box Top Bottom TopInside BottomInside
    or not {                       % => Viewport Box Top Bottom
    } {                            % => Viewport Box Top Bottom
% draw generic box
      3 index 3 index
      box-generic-show 

      2 index get-left 
      3 index get-top 
      4 index get-default-baseline
      sub 
      moveto
      
      2 index get-text             % => Viewport Box Top Bottom Text
      
      3 index
      box-text-find-font            % => Viewport Box Top Bottom Text <<Font>>
      setfont
      show                         % => Viewport Box Top Bottom

% draw text decoration
      2 index /text-decoration get-css-value 
      3 index get-text             % => Viewport Box Top Bottom Decoration Text
% underline
      1 index /underline get {     % => Viewport Box Top Bottom Decoration Text
        dup 
        5 index                    % => Viewport Box Top Bottom Decoration Text Text Box
        box-text-draw-underline    % => Viewport Box Top Bottom Decoration Text
      } if
      
% overline
      1 index /overline get {      % => Viewport Box Top Bottom Decoration Text
        dup 
        5 index                    % => Viewport Box Top Bottom Decoration Text Text Box
        box-text-draw-overline     % => Viewport Box Top Bottom Decoration Text
      } if

% line-through
      1 index /line-through get {  % => Viewport Box Top Bottom Decoration Text
        dup 
        5 index                    % => Viewport Box Top Bottom Decoration Text Text Box
        box-text-draw-line-through % => Viewport Box Top Bottom Decoration Text
      } if

      pop pop 
    } ifelse
  } ifelse                         % => Viewport Box Top Bottom

  pop pop pop pop
} def

/get-encoding {
  /Encoding get
} def

/get-text {                        % => Box
  /Text get
} def

/put-encoding {                    % => Encoding Box
  exch
  /Encoding
  exch
  put
} def

/put-text {                        % => Text Box
  exch
  /Text
  exch
  put
} def

%%%%%%%%%%%%%%%%%%%%

/show-enc-text-box {
% Check if this box will be cut on the bottom edge of the page (i.e. bottom < 0)
  dup get-bottom bmargin gt {
    show-enc-text-box-force
  } {
% do not display this box; also, store the additional offset to show this text on the next page
    /vdelta vdelta 2 index get-top bmargin sub max def
    pop
  } ifelse
} def

/show-enc-text-box-force {         % => Box
  show-generic-box                 % => Box
  currentpoint 
  2 index get-content              % => Box X Y Content
  aload pop                       
  show-enc-text
  moveto  

  dup get-text-decoration          % => Box Decor
  dup /Underline known {
    currentpoint
    3 index get-content            % => Box Decor X Y [Text <<Font>>]
    aload pop pop 
    draw-underline
    moveto
  } if

  dup /Overline known {
    currentpoint
    3 index get-content 
    aload pop pop 
    draw-overline
    moveto
  } if

  dup /Line-Through known {
    currentpoint
    3 index get-content 
    aload pop pop 
    draw-line-through
    moveto
  } if

  pop                              % => Box

} def

/show-enc-text {                   % => Text <<Font>>
  setfont                          % => Text 
  show                             % => 
} def        
